/*
 * EnigmaGM - A feature rich guild management system.
 * Copyright (C) 2007 ajiaojr.
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */
package org.ajiaojr.enigmagm.client.dialog;

import org.ajiaojr.enigmagm.client.Paged;
import org.ajiaojr.enigmagm.client.SortablePaged;
import org.ajiaojr.enigmagm.client.data.Character;
import org.ajiaojr.enigmagm.client.data.Event;
import org.ajiaojr.enigmagm.client.data.Point;
import org.ajiaojr.enigmagm.client.data.Purchase;
import org.ajiaojr.enigmagm.client.service.CharacterService;
import org.ajiaojr.enigmagm.client.service.EventService;
import org.ajiaojr.enigmagm.client.service.EventServiceAsync;
import org.ajiaojr.enigmagm.client.service.PointService;
import org.ajiaojr.enigmagm.client.service.PointServiceAsync;
import org.ajiaojr.enigmagm.client.service.PurchaseService;
import org.ajiaojr.enigmagm.client.service.PurchaseServiceAsync;

import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.SourcesTabEvents;
import com.google.gwt.user.client.ui.SourcesTableEvents;
import com.google.gwt.user.client.ui.TabListener;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.TableListener;
import com.google.gwt.user.client.ui.VerticalPanel;

import java.util.List;

/**
 * Dialog for displaying character details.
 * 
 * @author ajiaojr
 */
public class CharacterDetailsDialog extends DialogBox {
  private class EventsGrid extends Paged {

    public static final int MAX_RESULTS = 15;

    public EventsGrid(Panel parent) {
      super(parent, MAX_RESULTS);
    }

    public void populate() {
      EventServiceAsync attendanceService = EventService.Util.getInstance();

      attendanceService.findAttendedEvents(character.getCharacterID(),
          firstResult, maxResults, new AsyncCallback() {

            public void onFailure(Throwable caught) {
              Window.alert(caught.getMessage());
            }

            public void onSuccess(Object result) {
              panel.clear();

              final List events = (List) result;

              Grid grid = new Grid(events.size() + 1, 3);

              grid.setWidth("100%");
              grid.setStyleName("gwt-table");
              grid.addStyleName("dataTable");
              grid.setText(0, 0, MESSAGES.tabs_attendance_event_name());
              grid.setText(0, 1, MESSAGES.tabs_attendance_event_time());
              grid.setText(0, 2, MESSAGES.tabs_attendance_event_comments());
              grid.getRowFormatter().addStyleName(0, "header");
              grid.getColumnFormatter().setWidth(0, "150px");
              grid.getColumnFormatter().setWidth(1, "120px");
              grid.addTableListener(new TableListener() {

                public void onCellClicked(SourcesTableEvents sender, int row,
                    int cell) {
                  if (row < 1)
                    return;
                  Event e = (Event) events.get(row - 1);
                  EventDetailsDialog edd = new EventDetailsDialog(e);
                  hide();
                  edd.show();
                }
              });

              for (int i = 0; i < events.size(); i++) {
                Event e = (Event) events.get(i);
                int currentRow = i + 1;

                grid.setText(currentRow, 0, e.getRaidBossName());
                grid.setText(currentRow, 1, dateTimeFormat.format(e
                    .getEventTimeAsDate()));
                grid.setText(currentRow, 2, e.getComments());
                grid.getRowFormatter().addStyleName(currentRow, "clickable");
                grid.getRowFormatter().addStyleName(currentRow, "highlight");
              }
              panel.add(grid);
              attachNavBar();
            }
          });
    }

  }

  private class PointsGrid extends Paged {
    public static final int MAX_RESULTS = 20;

    public PointsGrid(Panel parent) {
      super(parent, MAX_RESULTS);
    }

    public void populate() {
      PointServiceAsync pointService = PointService.Util.getInstance();

      pointService.findByCharacterID(character.getCharacterID(), firstResult,
          maxResults, new AsyncCallback() {

            public void onFailure(Throwable caught) {
              Window.alert(caught.getMessage());
            }

            public void onSuccess(Object result) {
              panel.clear();

              final List points = (List) result;
              int pointsCount = points.size();

              Grid grid = new Grid(pointsCount + 1, 5);
              grid.setWidth("100%");
              grid.setStyleName("gwt-table");
              grid.addStyleName("dataTable");
              grid.setText(0, 0, MESSAGES.tabs_points_pointSystemName());
              grid.setText(0, 1, MESSAGES.tabs_points_current());
              grid.setText(0, 2, MESSAGES.tabs_points_earned());
              grid.setText(0, 3, MESSAGES.tabs_points_spent());
              grid.setText(0, 4, MESSAGES.tabs_points_adjustment());
              grid.getRowFormatter().addStyleName(0, "header");
              grid.getColumnFormatter().setWidth(0, "120px");
              grid.getColumnFormatter().setWidth(1, "80px");
              grid.getColumnFormatter().setWidth(2, "80px");
              grid.getColumnFormatter().setWidth(3, "80px");

              for (int i = 0; i < pointsCount; i++) {
                Point r = (Point) points.get(i);

                int currentRow = i + 1;
                grid.setText(currentRow, 0, r.getPointSystemName());
                grid.setText(currentRow, 1, Double.toString(r.getCurrent()));
                grid.setText(currentRow, 2, Double.toString(r.getEarned()));
                grid.setText(currentRow, 3, Double.toString(r.getSpent()));
                grid.setText(currentRow, 4, Double.toString(r.getAdjustment()));
              }

              panel.add(grid);
              attachNavBar();
            }
          });
    }

  }

  private class PurchasesGrid extends SortablePaged {
    private static final int MAX_RESULTS = 20;

    public PurchasesGrid(Panel parent) {
      super(parent, MAX_RESULTS, "event_time");
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.ajiaojr.enigmagm.client.Paged#populate()
     */
    public void populate() {
      PurchaseServiceAsync purchaseService = PurchaseService.Util.getInstance();

      purchaseService.findByCharacterID(character.getCharacterID(),
          sortAttribute, ascending, firstResult, maxResults,
          new AsyncCallback() {

            public void onFailure(Throwable caught) {
              Window.alert(caught.getMessage());
            }

            public void onSuccess(Object result) {
              panel.clear();

              final List purchases = (List) result;
              int purchasesCount = purchases.size();

              Grid grid = new Grid(purchasesCount + 1, 3);
              grid.setWidth("100%");
              grid.setStyleName("gwt-table");
              grid.addStyleName("dataTable");
              grid.setText(0, 0, MESSAGES.tabs_purchases_itemName());
              grid.setText(0, 1, MESSAGES.tabs_purchases_event_name());
              grid.setText(0, 2, MESSAGES.tabs_purchases_event_time());
              grid.getRowFormatter().addStyleName(0, "header");
              grid.getRowFormatter().addStyleName(0, "clickable");
              grid.getColumnFormatter().setWidth(0, "160px");
              grid.getColumnFormatter().setWidth(1, "160px");
              grid.addTableListener(new TableListener() {
                public void onCellClicked(SourcesTableEvents sender, int row,
                    int cell) {
                  if (row == 0) {
                    switch (cell) {
                      case 0:
                        setSortAttribute("item_name");
                        break;
                      case 1:
                        setSortAttribute("event_name");
                        break;
                      case 2:
                        setSortAttribute("event_time");
                        break;
                    }
                  } else {
                    switch (cell) {
                      case 0:
                        ItemDetailsDialog idd =
                            new ItemDetailsDialog(((Purchase) purchases
                                .get(row - 1)).getItemID());
                        idd.show();
                    }
                  }
                }
              });

              for (int i = 0; i < purchasesCount; i++) {
                Purchase purchase = (Purchase) purchases.get(i);

                int currentRow = i + 1;
                grid.setText(currentRow, 0, purchase.getItemName());
                grid.setText(currentRow, 1, purchase.getRaidBossName());
                grid.setText(currentRow, 2, dateTimeFormat.format(purchase
                    .getEventTimeAsDate()));
                grid.getRowFormatter().addStyleName(currentRow, "highlight");
                grid.getRowFormatter().addStyleName(currentRow, "clickable");

              }

              panel.add(grid);
              attachNavBar();
            }
          });
    }
  }

  private static final CharacterDetailsDialogMessages MESSAGES =
      (CharacterDetailsDialogMessages) GWT
          .create(CharacterDetailsDialogMessages.class);

  private org.ajiaojr.enigmagm.client.data.Character character;

  private Label characterNameLabel;

  private Label classLabel;

  private DateTimeFormat dateTimeFormat =
      DateTimeFormat.getFormat("dd MMM yyyy HH:mm");

  private EventsGrid eventsGrid;

  private PointsGrid pointsGrid;

  private PurchasesGrid purchasesGrid;

  private TabPanel tabPanel;

  public CharacterDetailsDialog(Character character) {
    super(true);
    this.character = character;
    init();
  }

  public CharacterDetailsDialog(int characterID) {
    super(true);
    init();
    CharacterService.Util.getInstance().findByCharacterID(characterID,
        new AsyncCallback() {

          public void onFailure(Throwable caught) {
            Window.alert(caught.getMessage());
          }

          public void onSuccess(Object result) {
            character = (org.ajiaojr.enigmagm.client.data.Character) result;
            showContents();
          }
        });
  }

  public org.ajiaojr.enigmagm.client.data.Character getCharacter() {
    return character;
  }

  public void setCharacter(org.ajiaojr.enigmagm.client.data.Character character) {
    this.character = character;
  }

  public void show() {
    showContents();
    super.show();
  }

  private void init() {
    final VerticalPanel verticalPanel = new VerticalPanel();
    setWidget(verticalPanel);
    verticalPanel.setSize("500px", "100%");

    final HorizontalPanel horizontalPanel = new HorizontalPanel();
    verticalPanel.add(horizontalPanel);
    horizontalPanel.setWidth("100%");

    final VerticalPanel verticalPanel_3 = new VerticalPanel();
    horizontalPanel.add(verticalPanel_3);
    verticalPanel_3.setWidth("100%");
    horizontalPanel.setCellWidth(verticalPanel_3, "50%");

    final HorizontalPanel horizontalPanel_1 = new HorizontalPanel();
    verticalPanel_3.add(horizontalPanel_1);
    horizontalPanel_1.setWidth("100%");
    horizontalPanel_1.setSpacing(5);

    characterNameLabel = new Label();
    horizontalPanel_1.add(characterNameLabel);
    horizontalPanel_1.setCellHorizontalAlignment(characterNameLabel,
        HasHorizontalAlignment.ALIGN_CENTER);
    horizontalPanel_1.setCellWidth(characterNameLabel, "100px");

    final VerticalPanel verticalPanel_4 = new VerticalPanel();
    horizontalPanel.add(verticalPanel_4);
    verticalPanel_4.setWidth("100%");
    horizontalPanel.setCellWidth(verticalPanel_4, "50%");

    final HorizontalPanel horizontalPanel_2 = new HorizontalPanel();
    verticalPanel_4.add(horizontalPanel_2);
    horizontalPanel_2.setWidth("100%");
    horizontalPanel_2.setSpacing(5);

    classLabel = new Label();
    horizontalPanel_2.add(classLabel);
    horizontalPanel_2.setCellWidth(classLabel, "100px");
    horizontalPanel_2.setCellHorizontalAlignment(classLabel,
        HasHorizontalAlignment.ALIGN_CENTER);

    final HTML html = new HTML("<hr/>");
    verticalPanel.add(html);

    tabPanel = new TabPanel();
    verticalPanel.add(tabPanel);
    tabPanel.addTabListener(new TabListener() {
      public boolean onBeforeTabSelected(SourcesTabEvents sender, int tabIndex) {
        return true;
      }

      public void onTabSelected(SourcesTabEvents sender, int tabIndex) {
        switch (tabIndex) {
          case 0:
            pointsGrid.populate();
            break;
          case 1:
            purchasesGrid.populate();
            break;
          case 2:
            eventsGrid.populate();
            break;
        }
      }
    });
    tabPanel.setWidth("100%");

    final VerticalPanel pointsPanel = new VerticalPanel();
    tabPanel.add(pointsPanel, MESSAGES.tabs_points());
    pointsPanel.setSpacing(5);
    pointsPanel.setStyleName("gwt-TabBody");

    final VerticalPanel verticalPanel_2 = new VerticalPanel();
    pointsPanel.add(verticalPanel_2);
    verticalPanel_2.setWidth("100%");
    pointsGrid = new PointsGrid(verticalPanel_2);

    final VerticalPanel purchasesPanel = new VerticalPanel();
    tabPanel.add(purchasesPanel, MESSAGES.tabs_purchases());
    purchasesPanel.setSpacing(5);
    purchasesPanel.setStyleName("gwt-TabBody");

    final VerticalPanel verticalPanel_5 = new VerticalPanel();
    purchasesPanel.add(verticalPanel_5);
    verticalPanel_5.setWidth("100%");
    purchasesGrid = new PurchasesGrid(verticalPanel_5);

    final VerticalPanel attendancePanel = new VerticalPanel();
    tabPanel.add(attendancePanel, MESSAGES.tabs_attendance());
    attendancePanel.setStyleName("gwt-TabBody");
    attendancePanel.setSpacing(5);

    final VerticalPanel verticalPanel_1 = new VerticalPanel();
    attendancePanel.add(verticalPanel_1);
    verticalPanel_1.setWidth("100%");

    eventsGrid = new EventsGrid(verticalPanel_1);

    final Label attendanceTipLabel =
        new Label(MESSAGES.tip(MESSAGES.tabs_attendance_tip()));
    attendancePanel.add(attendanceTipLabel);
    attendanceTipLabel.setStyleName("tip");

    setPopupPosition((Window.getClientWidth() - 500) / 2, (Window
        .getClientHeight() - 300) / 2);
  }

  /**
   * 
   */
  private void showContents() {
    if (character != null) {
      setHTML(MESSAGES.title(character.getCharacterName()));
      characterNameLabel.setText(MESSAGES.character_name(character
          .getCharacterName()));
      classLabel.setText(MESSAGES
          .character_class(character.getCharacterClass()));
      tabPanel.selectTab(0);
    }
  }
}
